package MTT::Controller::Reports;
use Moose;
use namespace::autoclean;

BEGIN {extends 'Catalyst::Controller'; }

=head1 NAME

MTT::Controller::Reports - Catalyst Controller

=head1 DESCRIPTION

Catalyst Controller.

=head1 METHODS

=cut


=head2 index

=cut
use Data::Dumper;

use utf8;

use POSIX qw(strftime);

use MTT::Libs::ObjectAccess;
use MTT::Libs::Report;
use MTT::Libs::Report::SimpleReport;
use MTT::Libs::ReportData;
use MTT::Form::Report;


sub index :Path {
    my ( $self, $c, $id_type, $id_switch ) = @_;

	my $report = MTT::Libs::Report->new( schema => $c->model('DBIC') );
	my $id_report = $c->req->query_params->{id_report};

	if ( $c->req->method eq 'GET' && !$c->req->query_params->{run} ) {
		if ( $id_report ) {
			$report->load($id_report);
		}
		else {
			if ( $id_switch ) {
				my $switch = $c->model('DBIC::Switch')->find($id_switch);
				$report->switches( [$switch] ); 
			}
			elsif ( $id_type ) {
				my @switches = $c->model('DBIC::Switch')->search({id_type => $id_type});
				$report->switches( \@switches );
			}
		}
	}
	else {

		$c->user_log->info('Отчет', 'report');

		if ( $c->req->query_params->{run} ) {
			$report->load($id_report);
#die Dumper( $report->props )			
		}
		else {
			$report->process( $self->convert_params( $c ) );
		}


		$report->make_report( $c );


		if ( $c->req->params->{format} eq 'html' ) {

			my $table = $report->get_html();

			my %rt = (
				hour => 'по часам', 
				quarter => 'по четвертям', 
				cnn => 'по ЧНН2', 
				cnn2 => 'по ЧНН'
			);

			my $rep_name = 'Отчет по ' . ( $report->{is_mask} ? 'маскам ' : 'транкам ' ) 
				    	 . $rt{ $report->props->{report_type} };
#			$rep_name .= '<br />Всего строк: ' . $report->rows;

			$c->stash(
				report_name => $rep_name,
				report_table => $table
			);
		}
		elsif ( $c->req->params->{format} eq 'csv' ) {
			my $file = $report->get_csv($c);
			my $fh	 = IO::File->new( $file, 'r' ) || die $!;
			$fh->binmode();
			my $file_num = $c->session->{report_csv_num} || 0;
			$file_num++ unless $report->name;

			my $filename = ( $report->name ? $report->name : "report_$file_num" ) . '.csv';
			utf8::encode( $filename );

			$c->response->content_type( qq{text/csv; name="$filename"} );
			$c->res->header(
				'Content-Disposition' => qq{attachment; filename="$filename"}
			);

			$c->session->{report_csv_num} = $file_num;

			$c->response->body( $fh );
			return;
		}
		elsif ( $c->req->params->{format} eq 'excel' ) {
			my $file = $report->get_excel($c);
			my $fh	 = IO::File->new( $file, 'r' ) || die $!;
			$fh->binmode();
			my $file_num = $c->session->{report_excel_num} || 0;
			$file_num++ unless $report->name;

			my $filename = ( $report->name ? $report->name : "report_$file_num" ) . '.xls';
			utf8::encode( $filename );

			$c->response->content_type( qq{application/excel; name="$filename"});
			$c->res->header(
				'Content-Disposition' => qq{attachment; filename="$filename"}
			);

			$c->session->{report_excel_num} = $file_num;

			$c->response->body( $fh );
			return;
		}
		else {
			$c->res->body('Этот тип отчета еще не реализован, выберите другой');
		}

#		$report->process( $c->req->params );
#		my $concrete = MTT::Libs::Report::SimpleReport->new(schema => $c->model('DBIC'));
#		my $data = $concrete->get_report($report);

	}

	$c->stash->{report} = $report;

	my $report_data = MTT::Libs::ReportData->instance->get_data();
	my $masks = MTT::Libs::ReportData->instance->get_masks();

	my $form = MTT::Form::Report->new(
		schema => $c->model('DBIC')->schema,
		ctx => $c
	);

	$c->stash(
		template => 'report.tt2',
		report_data => $report_data,
		masks	  => $masks, 
		date_from => strftime('%Y-%m-%d 00:00', localtime),
		date_to   => strftime('%Y-%m-%d 23:59', localtime),
		form => $form
	);

}

sub convert_params {
	my ($self, $c) = @_;

	my $p = $c->req->params;

	my $res_p = { %$p };

	$res_p->{user} = $c->user;

	if ( $res_p->{'switches_do[]'} ) {
		$res_p->{switches_do} = delete $res_p->{'switches_do[]'};
		$res_p->{switches_do} = [ $res_p->{switches_do} ]
			unless ref $res_p->{switches_do};
	}
	$res_p->{switches_do} = [] unless $res_p->{switches_do};

	if ( $res_p->{'trunks_do[]'} ) {
		$res_p->{trunks_do} = delete $res_p->{'trunks_do[]'};
		$res_p->{trunks_do} = [ $res_p->{trunks_do} ]
			unless ref $res_p->{trunks_do};
	}
	$res_p->{trunks_do} = [] unless $res_p->{trunks_do};

	if ( $res_p->{'companies_do[]'} ) {
		$res_p->{companies_do} = delete $res_p->{'companies_do[]'};
		$res_p->{companies_do} = [ $res_p->{companies_do} ]
			unless ref $res_p->{companies_do};
	}
	$res_p->{companies_do} = [] unless $res_p->{companies_do};

	if ( $res_p->{'params_do[]'} ) {
		$res_p->{params_do} = delete $res_p->{'params_do[]'};
		$res_p->{params_do} = [ $res_p->{params_do} ]
			unless ref $res_p->{params_do};
	}
	elsif ( $res_p->{params} ) {
		$res_p->{params_do} = [ split(/\s*,\s*/, $res_p->{params}) ];
	}
	$res_p->{params_do} = [] unless $res_p->{params_do};

	if ( $res_p->{'groups_do[]'} ) {
		$res_p->{groups_do} = delete $res_p->{'groups_do[]'};
		$res_p->{groups_do} = [ $res_p->{groups_do} ]
			unless ref $res_p->{groups_do};
	}
	elsif ( $res_p->{groups} ) {
		$res_p->{groups_do} = [ split(/\s*,\s*/, $res_p->{groups}) ];
	}
	$res_p->{groups_do} = [] unless $res_p->{groups_do};

	return $res_p;
}


sub save : Local {
	my ($self, $c) = @_;

	unless ( $c->req->params->{report_name} ) {
		$c->stash->{json_data}->{result} = 'ERROR: Отсутствует название отчета';
		$c->detach('View::JSON');
	}

	my $report = MTT::Libs::Report->new(schema => $c->model('DBIC'));
	if ( $c->req->params->{type} eq 'save' ) {
		$report->id( $c->req->params->{id_report} );
	}
	$c->req->params->{id_user} = $c->user->id;
	$report->process( $self->convert_params( $c ) );

	if ( $report->save() ) {
		$c->stash->{json_data}->{result} = 'OK';
	}
	else {
		$c->stash->{json_data}->{result} = 'ERROR: Не удалось сохранить отчет';
	}

	$c->forward('View::JSON');
}


sub get_switches: Path('/reports/switches') {
	my ($self, $c) = @_;

	my $type_ids = $c->req->params->{'switch_types[]'};
	$type_ids = [ $type_ids ] unless ref $type_ids;

	my (@switches, %companies, %cities, %obls, %fos, %trunks);

	if ( $type_ids->[0] == 0 ) {
		my $rs_s = $c->model('DBIC::Switch')->search({status => 1});
		$rs_s->result_class('DBIx::Class::ResultClass::HashRefInflator');
		while ( my $switch = $rs_s->next() ) {
			push @switches, {id => $switch->{id}, name => $switch->{descr}};
		}

		my $rs_t = $c->model('DBIC::Trunk')->search({created => { '>=' => \'DATE(NOW())' }});
		$rs_t->result_class('DBIx::Class::ResultClass::HashRefInflator');
		while ( my $trunk = $rs_t->next() ) {
			$companies{ $trunk->{company_name} } = 1;
			$cities{ $trunk->{city} } = 1;
			$obls{ $trunk->{oblast} } = 1;
			$fos{ $trunk->{fo} } = 1;
			$trunks{ $trunk->{trunk} } = 1;
		}
	}
	else {
		foreach my $id_type ( @$type_ids ) {
			my $switches = $c->model('DBIC::Switch')->search({
					id_type => $id_type,
					status => 1
				}
			);
			$switches->result_class('DBIx::Class::ResultClass::HashRefInflator');
			while ( my $switch = $switches->next() ) {
				push @switches, {id => $switch->{id}, name => $switch->{descr}};

				my $trunks = $c->model('DBIC::Trunk')->search({
							switch => $switch->{host_code},
							created => { '>=' => \'DATE(NOW())' }});
				$trunks->result_class('DBIx::Class::ResultClass::HashRefInflator');

				while ( my $trunk = $trunks->next ) {
					$companies{ $trunk->{company_name} } = 1;
					$cities{ $trunk->{city} } = 1;
					$obls{ $trunk->{oblast} } = 1;
					$fos{ $trunk->{fo} } = 1;
					$trunks{ $trunk->{trunk} } = 1;
				}
			}
		}
	}

	$c->stash->{json_data} = { 
		switches  => \@switches,
		companies => \%companies,
		cities 	  => \%cities,
		obls	  => \%obls,
		fos 	  => \%fos,
		trunks 	  => \%trunks
	};

	$c->component('View::JSON')->encoding('utf-8');
	$c->forward('View::JSON');
}

sub get_switches_by_area: Path('switches_by_area') {
	my ($self, $c) = @_;

	my $name = $c->req->params->{name};
	my $vals = $c->req->params->{'vals[]'};
	$vals = [ $vals ] unless ref $vals;

	my (@switches, @switch_types, @companies, @cities, @obls, @fos, @trunks);
	my (%switch_types, %companies, %cities, %obls, %fos, %trunks);
	my %host_code;
	my $rs;

	my $selected = '';

	my $is_all = $vals->[0] =~ /^0$/;

	if ( $is_all ) {
		$rs = $c->model('DBIC::Trunk')->search({created => { '>=' => \'DATE(NOW())' }}); 
		foreach my $switch ( $c->model('DBIC::Switch')->all() ) {
			push @switches, {id => $switch->id, name => $switch->descr} unless $host_code{ $switch->host_code }++;
			push @switch_types, {id => $switch->id_type->id, type => $switch->id_type->type};
		}
	}
	else {
		if ( $name eq 'companies' ) {
			$rs = $c->model('DBIC::Trunk')->search({company_name => { 'IN' => $vals }, created => { '>=' => \'DATE(NOW())' } }); 
			$selected = 'companies';
		}
		elsif ( $name eq 'cities' ) {
			$rs = $c->model('DBIC::Trunk')->search({city => { 'IN' => $vals }, created => { '>=' => \'DATE(NOW())' } }); 
			$selected = 'cities';
		}
		elsif ( $name eq 'obls' ) {
			$rs = $c->model('DBIC::Trunk')->search({oblast => { 'IN' => $vals }, created => { '>=' => \'DATE(NOW())' } }); 
			$selected = 'obls';
		}
		elsif ( $name eq 'fos' ) {
			$rs = $c->model('DBIC::Trunk')->search({fo => { 'IN' => $vals }, created => { '>=' => \'DATE(NOW())' } }); 
			$selected = 'fos';
		}
		elsif ( $name eq 'trunks' ) {
			$rs = $c->model('DBIC::Trunk')->search({trunk => { 'IN' => $vals }, created => { '>=' => \'DATE(NOW())' } }); 
			$selected = 'trunks';
		}
		elsif ( $name eq 'switches_do' ) { 
			my @sws;
			foreach ( @$vals ) {
				my $sw = $c->model('DBIC::Switch')->find($_);
				push @sws, $sw->host_code if $sw;
			}

			$rs = $c->model('DBIC::Trunk')->search({switch => { 'IN' => \@sws }, created => { '>=' => \'DATE(NOW())' } }); 
			$selected = 'switch';

		}
	}

	$rs->result_class('DBIx::Class::ResultClass::HashRefInflator');
	while ( my $trunk = $rs->next() ) {
		unless ( $is_all ) { 
			my $sws = $c->model('DBIC::Switch')->search({host_code => $trunk->{switch}});
			if ( my $switch = $sws->next ) {
				push @switches, {id => $switch->id, name => $switch->descr} unless $host_code{ $switch->host_code }++;
				push @switch_types, {id => $switch->id_type->id, type => $switch->id_type->type};
			}	
		}

		push @companies, $trunk->{company_name} unless $companies{ $trunk->{company_name} }++;
		push @cities, $trunk->{city} unless $companies{ $trunk->{city} }++;
		push @obls, $trunk->{oblast} unless $companies{ $trunk->{oblast} }++;
		push @fos, $trunk->{fo} unless $companies{ $trunk->{fo} }++;
		push @trunks, $trunk->{trunk} unless $companies{ $trunk->{trunk} }++;
	}

	@companies = sort @companies;
	@cities = sort @cities;
	@obls = sort @obls;
	@fos = sort @fos;
	@trunks = sort @trunks;

	$c->stash->{json_data} = { 
		switches => \@switches,
		switch_types => \@switch_types,
		companies => \@companies,
		cities => \@cities,
		obls => \@obls,
		fos  => \@fos,
		trunks => \@trunks,
		selected => $selected
	};

	$c->component('View::JSON')->encoding('utf-8');
	$c->forward('View::JSON');
}


=head1 AUTHOR

A clever guy

=head1 LICENSE

This library is free software. You can redistribute it and/or modify
it under the same terms as Perl itself.

=cut

__PACKAGE__->meta->make_immutable;

1;
